home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
- * POOL.C
- * MSL 9/3/90
- * Copyright (c) 1990 Mark Lutton
- * All Rights Reserved
- */
-
- #ifdef _lint
- #define NOREF(a) a = a
- #else
- #define NOREF(a) a
- #endif
-
- #define NOCOMM
- #define NOMINMAX
-
- #include <windows.h>
- #include <stdlib.h> /* for rand() */
- #include "pool.h"
-
-
-
- HANDLE hInst; /* Global Instance Handle */
-
- long FAR PASCAL MainFormWndProc(HWND, unsigned, WORD, LONG);
-
- WORD wAlertTimerId; /* ID of Alert Timer. */
- WORD wTimerTicks=1; /* Timer interval, initially 1000 times/second. */
- WORD wFactor=50; /* How many points per interval. */
-
- WORD wTableWidth=345;
- WORD wTableHeight=196;
- WORD wPoolStartX=0;
- WORD wPoolStartY=0;
- int nXDir = 1;
- int nYDir = 1;
- int nX, nY;
- RECT mainrect;
- RECT winrect;
- BOOL fReverse = FALSE;
-
- WORD wOptionsWindowHeight;
- WORD wOptionsWindowWidth;
- WORD wOptionsPoolStartX;
- WORD wOptionsPoolStartY;
- WORD wOptionsPoolTableWidth;
- WORD wOptionsPoolTableHeight;
- WORD wOptionsPoolSpeed;
-
- BOOL fRun = TRUE;
-
- char szAppName [] = "Pool";
-
- VOID FAR PASCAL PoolTimerTick(HWND hWnd, WORD wMsg, int nIDEvent, DWORD dwTime);
- BOOL FAR PASCAL OptionsDlgProc(HWND hDlg, unsigned iMessage,
- WORD wParam, LONG lParam);
- BOOL PoolTimerInit(HWND hWnd);
- VOID PoolTimerKill(HWND hWnd);
- VOID NewOptions(HWND hWnd);
-
-
- /******************************************************************
- * WinMain()
- */
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR CmdLine, int CmdShow)
- {
- HWND hWnd;
- MSG msg;
-
- NOREF(CmdLine);
- NOREF(CmdShow);
-
- hInst = hInstance;
-
- if (!hPrevInstance) {
- WNDCLASS WndClass;
- WndClass.lpszClassName = szAppName;
- WndClass.hInstance = hInstance;
- WndClass.lpfnWndProc = MainFormWndProc;
- WndClass.style = CS_HREDRAW | CS_VREDRAW;
- WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
- WndClass.hIcon = NULL;
- WndClass.lpszMenuName = "PoolMenu";
- WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
- WndClass.cbClsExtra = NULL;
- WndClass.cbWndExtra = NULL;
- if (!RegisterClass(&WndClass))
- return(NULL);
- }
-
- hWnd = CreateWindow(szAppName, /* Window class name */
- szAppName, /* Window caption */
- WS_OVERLAPPEDWINDOW,/* window style */
- 0, /* initial x position */
- 0, /* initial y position */
- CW_USEDEFAULT, /* initial x state */
- 0, /* initial y state */
- NULL, /* parent window handle */
- NULL, /* window menu handle */
- hInstance, /* program instance handle */
- NULL); /* create parameters */
- if (!hWnd)
- return NULL;
-
- /* Application initialization. */
- nX = (int) wPoolStartX;
- nY = (int) wPoolStartY;
-
-
- while (GetMessage (&msg, NULL, 0, 0)){
- (VOID) TranslateMessage (&msg) ;
- (VOID) DispatchMessage (&msg) ;
- }
- return ((int)msg.wParam);
- }
-
-
-
- long FAR PASCAL MainFormWndProc(hWnd, message, wParam, lParam)
- HWND hWnd;
- unsigned message;
- WORD wParam;
- LONG lParam;
- {
- static FARPROC lpfnPoolOptionsDlg;
- int nRetval;
-
- switch (message){
- case WM_CREATE:
- /* Set up pleasing initial options. */
- wOptionsWindowWidth = 396;
- wOptionsWindowHeight = 245;
- wOptionsPoolTableWidth = 345;
- wOptionsPoolTableHeight = 196;
- wOptionsPoolStartX = 297;
- wOptionsPoolStartY = 158;
- wOptionsPoolSpeed = 50;
- NewOptions(hWnd);
-
- lpfnPoolOptionsDlg = MakeProcInstance(OptionsDlgProc, hInst);
- (VOID)PoolTimerInit(hWnd);
- (VOID)ShowWindow(hWnd,SW_SHOWNORMAL);
- UpdateWindow(hWnd);
- break;
-
- case WM_COMMAND:
- switch (wParam) {
- case IDM_OPTIONS:
- fRun = FALSE; /* Freeze while we set options. */
- GetClientRect(hWnd, &winrect);
- nRetval = DialogBox(hInst, "OPTIONS", hWnd, lpfnPoolOptionsDlg);
- if (nRetval == 1) {
- NewOptions(hWnd);
- }
- fRun = TRUE;
- break;
- case IDM_FREEZE:
- fRun = !fRun; /* Toggle freeze/unfreeze. */
- break;
- case IDM_REVERSE:
- fRun = FALSE;
- fReverse = TRUE;
- fRun = TRUE;
- break;
- case IDM_EXIT:
- fRun = FALSE;
- if (MessageBox(hWnd, "End the program?",
- "Pool", MB_OKCANCEL) == IDOK) {
- (VOID) SendMessage(hWnd, WM_CLOSE, 0, 0L);
- }
- fRun = TRUE;
- break;
- case IDM_ABOUT:
- fRun = FALSE;
- (VOID) MessageBox(hWnd, "Windows Pool 1.0 by Mark Lutton, 9/3/90\n"
- "Thanks to Tim Peters and Ken Marks for the ideas.\n"
- "Copyright (c) 1990 Mark Lutton.\nAll rights reserved.",
- szAppName, MB_ICONASTERISK | MB_OK);
- fRun = TRUE;
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
-
- case WM_ENDSESSION:
- PoolTimerKill(hWnd);
- (VOID)DestroyWindow(hWnd);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:return(DefWindowProc(hWnd,message,wParam,lParam));
- }
- return (NULL);
- }
-
-
- /* Function to start up the timer. */
- BOOL PoolTimerInit(HWND hWnd)
- {
- FARPROC lpfnTimerProc;
-
- lpfnTimerProc = MakeProcInstance(PoolTimerTick, hInst);
- wAlertTimerId = SetTimer(hWnd, (short)hWnd, wTimerTicks, lpfnTimerProc);
- return (wAlertTimerId != 0);
-
- }
-
- VOID PoolTimerKill(HWND hWnd)
- {
- (VOID) KillTimer(hWnd, (short)hWnd);
- }
-
-
- /* Timer tick -- draw one dot (4-way symmetrical) and then */
- /* set next x/y values. */
- /* Note that this application does not respond to WM_PAINT */
- /* messages; we do not save a picture of the window anywhere. */
- /* (We could clear the screen in response to WM_PAINT.) */
-
- VOID FAR PASCAL PoolTimerTick(HWND hWnd, WORD wMsg, int nIDEvent, DWORD dwTime)
- {
- HDC hDC;
- unsigned long ulPixel;
- static unsigned long XOR_VALUE = 0x00FFFFFFUL;
- WORD i;
- static int randcount = 0;
-
-
- NOREF(wMsg);
- NOREF(nIDEvent);
- NOREF(dwTime);
-
- if (!fRun)
- return;
-
- /* Every 1/10 of a second, advance the random number generator. */
- if (++randcount >= 100) {
- randcount = 0;
- (VOID)rand();
- }
-
-
- /* Draw. */
- hDC = GetDC(hWnd);
-
- GetClientRect(hWnd, &mainrect);
-
- for (i=wFactor; i; i--) {
- ulPixel = GetPixel(hDC, nX, nY) ^ XOR_VALUE;
- (VOID)SetPixel(hDC, nX, nY, ulPixel);
- ulPixel = GetPixel(hDC, nX, mainrect.bottom - nY) ^ XOR_VALUE;
- (VOID)SetPixel(hDC, nX, mainrect.bottom - nY, ulPixel);
- ulPixel = GetPixel(hDC, mainrect.right - nX, nY) ^ XOR_VALUE;
- (VOID)SetPixel(hDC, mainrect.right - nX, nY, ulPixel);
- ulPixel = GetPixel(hDC, mainrect.right - nX, mainrect.bottom - nY) ^ XOR_VALUE;
- (VOID)SetPixel(hDC, mainrect.right - nX, mainrect.bottom - nY, ulPixel);
-
- if (fReverse) {
- nXDir = 0 - nXDir; /* Next time through, will undo pixel */
- nYDir = 0 - nYDir; /* it just did and not leave a dropping. */
- fReverse = FALSE;
- }
- else {
- nX += nXDir;
- if (nX > (int)wTableWidth || nX < 0) {
- nXDir = 0 - nXDir;
- nX += nXDir;
- nX += nXDir;
- }
- nY += nYDir;
- if (nY > (int)wTableHeight || nY < 0) {
- nYDir = 0 - nYDir;
- nY += nYDir;
- nY += nYDir;
- }
- }
- }
-
- (VOID)ReleaseDC(hWnd, hDC);
- }
-
- /* Options dialog. */
- BOOL FAR PASCAL OptionsDlgProc(HWND hDlg, unsigned iMessage,
- WORD wParam, LONG lParam)
- {
- WORD wRand, wTemp;
-
- NOREF (lParam);
-
- switch (iMessage) {
- case WM_INITDIALOG:
- SetDlgItemInt(hDlg, OD_EDIT_WINWIDTH,
- (WORD)(winrect.right-winrect.left), 0);
- SetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT,
- (WORD)(winrect.bottom-winrect.top), 0);
- SetDlgItemInt(hDlg, OD_EDIT_STARTX, wPoolStartX, 0);
- SetDlgItemInt(hDlg, OD_EDIT_STARTY, wPoolStartY, 0);
- SetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, wTableWidth, 0);
- SetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, wTableHeight, 0);
- SetDlgItemInt(hDlg, OD_EDIT_SPEED, wFactor, 0);
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam) {
- case OD_OK:
- wOptionsWindowHeight = GetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT, NULL, FALSE);
- wOptionsWindowWidth = GetDlgItemInt(hDlg, OD_EDIT_WINWIDTH, NULL, FALSE);
- wOptionsPoolStartX = GetDlgItemInt(hDlg, OD_EDIT_STARTX, NULL, FALSE);
- wOptionsPoolStartY = GetDlgItemInt(hDlg, OD_EDIT_STARTY, NULL, FALSE);
- wOptionsPoolTableWidth = GetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, NULL, FALSE);
- wOptionsPoolTableHeight = GetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, NULL, FALSE);
- wOptionsPoolSpeed = GetDlgItemInt(hDlg, OD_EDIT_SPEED, NULL, FALSE);
- EndDialog(hDlg, 1);
- break;
-
- case OD_CANCEL:
- EndDialog(hDlg, 0);
- break;
-
- case OD_RANDOM:
- /* Put 4 random numbers into 4 parameters. */
- wOptionsWindowHeight = GetDlgItemInt(hDlg, OD_EDIT_WINHEIGHT, NULL, FALSE);
- wOptionsWindowWidth = GetDlgItemInt(hDlg, OD_EDIT_WINWIDTH, NULL, FALSE);
- /* Pool table dimensions are at least half the window */
- /* size to force some overlap. */
- /* Start the ball somewhere within the window. */
- wTemp = wOptionsWindowWidth / 2;
- wRand = ((WORD)rand()) % wTemp + wTemp;
- SetDlgItemInt(hDlg, OD_EDIT_TABLEWIDTH, wRand, 0);
- wRand = ((WORD)rand()) % wRand;
- SetDlgItemInt(hDlg, OD_EDIT_STARTX, wRand, 0);
- wTemp = wOptionsWindowHeight / 2;
- wRand = ((WORD)rand()) % wTemp + wTemp;
- SetDlgItemInt(hDlg, OD_EDIT_TABLEHEIGHT, wRand, 0);
- wRand = ((WORD)rand()) % wRand;
- SetDlgItemInt(hDlg, OD_EDIT_STARTY, wRand, 0);
- break;
-
- default:
- return FALSE;
- }
- break;
-
- default:
- return FALSE;
- }
-
- return TRUE;
-
- }
-
- /* OK, set the new options. */
- VOID NewOptions(HWND hWnd)
- {
- RECT NewRect;
- int nYCaption, nYMenu, nYFrame, nXFrame;
-
-
- wFactor = wOptionsPoolSpeed;
- wPoolStartX = wOptionsPoolStartX;
- wPoolStartY = wOptionsPoolStartY;
- wTableHeight = wOptionsPoolTableHeight;
- wTableWidth = wOptionsPoolTableWidth;
-
-
- /* Convert client rect to window rect. */
- nYCaption = GetSystemMetrics(SM_CYCAPTION);
- nYMenu = GetSystemMetrics(SM_CYMENU);
- nYFrame = GetSystemMetrics(SM_CYFRAME);
- nXFrame = GetSystemMetrics(SM_CXFRAME);
- GetWindowRect(hWnd, &NewRect);
-
- /* This will force repaint. */
- MoveWindow(hWnd, NewRect.left, NewRect.top,
- (int)wOptionsWindowWidth + nXFrame + nXFrame,
- (int)wOptionsWindowHeight + nYFrame + nYCaption +
- nYMenu + nYFrame,
- TRUE);
- nXDir = 1;
- nYDir = 1;
- nX = (int) wPoolStartX;
- nY = (int) wPoolStartY;
- InvalidateRect(hWnd, NULL, TRUE);
-
- }
-
-
- /* End of POOL.C */
-